#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.basic.security.oauth2.config;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.annotation.Resource;

/**
 * Description:
 * <p>
 *  Spring security 需要使用的 Bean的配置类
 *  这里必须使用@Autowired注入方法，降低注入级别
 *  否则会注入时机冲突
 * </p>
 *
 * @author wupanhua
 * @date 2019/8/6 15:28
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2019. All Rights Reserved.
 * </pre>
 */
@Configuration
public class BeanConfigure {

    @Resource
    private YkSecurityProperties ykSecurityProperties;

    /**
     * Description:
     * <MD5密码加密>
     * @author ywh
     * @date 13:36 2019/8/7
     * @return org.springframework.security.crypto.password.PasswordEncoder
     **/
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }



    @Bean
    public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
        OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }

    /**
     * Description:
     * <配置授权token管理类 AuthorizationServerTokenServices>
     * @author wenxiaopeng
     * @date 21:33 2020/04/14
     * @param tokenStore 1
     * @param clientDetailsService 2
     * @return org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices
     **/
    @Bean
    public AuthorizationServerTokenServices authorizationServerTokenServices(TokenStore tokenStore, ClientDetailsService clientDetailsService) {

        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore);
        defaultTokenServices.setClientDetailsService(clientDetailsService);
        defaultTokenServices.setAccessTokenValiditySeconds(ykSecurityProperties.getTokenExpireTime());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }

    /**
     * Description:
     * <配置token存储>
     * @author wupanhua
     * @date 16:04 2020-04-23
     * @param redisTemplate redis 操作模板
     * @return org.springframework.security.oauth2.provider.token.TokenStore
     **/
    @Bean
    public TokenStore tokenStore(StringRedisTemplate redisTemplate) {
        return new RedisTokenStore(redisTemplate.getConnectionFactory());
    }

}
